<template>
  <div class="api-design flex-column" :class="viewTheme">
    <div class="api-design-head  flex-row-center flex-row-between">
      <div class=" flex-row-center ">
        <MaskPopover>
          <div class="form-item  api-name">
            <span class="form-item-label"> 接口名称</span>
            <input class="form-item-content" placeholder="输入接口名称(50字符)" maxlength="50" v-model.trim="api.name" />
            <!-- <DivEdit placeholder="输入接口名称(50字符)" maxlength="50" v-model="api.name" /> -->
          </div>
          <template #content>
            <div class="form-item">
              <span class="form-item-label"> 接口别名</span>
              <input class="form-item-content" placeholder="输入接口别名(50字符)" maxlength="50" v-model="api.alias" />
              <!-- <DivEdit placeholder="别名(50字符)" maxlength="50" v-model="api.alias" /> -->
            </div>
          </template>
        </MaskPopover>
        <div class="form-item">
          <span class="form-item-label"> 接口分组</span>
          <div class="form-item-content">
            <MaskPopover>
              <input placeholder="接口分组" maxlength="50" v-model.trim="api.group" />
              <!-- {{ api.group || "默认分组" }} -->
              <template #content>
                <ApiGroup @change="(group) => (api.group = group)"> </ApiGroup>
              </template>
            </MaskPopover>
          </div>
        </div>
        <!-- <div class="form-item">
          <span class="form-item-label"> 接口别名</span>
          <input class="form-item-content" placeholder="输入接口别名(50字符)" maxlength="50" v-model="api.alias" />
          <DivEdit placeholder="别名(50字符)" maxlength="50" v-model="api.alias" />
        </div> -->
      </div>
      <div class="action flex-row-center">
        <Icon class="icon-gray click margin-right-5px" type="doc" title="复制接口"></Icon>
        <Icon class="icon-gray click margin-right-5px" type="set" title="设置"></Icon>
        <Icon class="icon-gray click margin-right-5px" type="remove" title="删除" @click="$emit('remove', api)"></Icon>
        <!-- <Icon class="icon-gray click margin-right-5px" type="close" title="删除" @click="$emit('remove', api)"></Icon>
        <Icon class="icon-mini click margin-right-5px" type="arrowDown" title="打开" @click="viewOpen = !viewOpen"></Icon> -->
      </div>
    </div>
    <div class="api-request flex-row-center ">
      <div class="form-item api-method ">
        <span class="form-item-label "> 请求类型</span>
        {{ api.method }}
        <select class="form-item-content" v-model="api.method">
          <option value="get">get</option>
          <option value="post">post</option>
          <option value="put">put</option>
          <option value="head">head</option>
          <option value="delete">delete</option>
        </select>
      </div>
      <div class="form-item ">
        <span class="form-item-label "> 请求地址</span>
        <input class="form-item-content api-url" :placeholder="tips.url" maxlength="2048" :title="tips.url" v-model="api.url" />
        <!-- <DivEdit class="form-item-content api-url" :placeholder="tips.url" maxlength="2048" :title="tips.url" v-model="api.url" /> -->
      </div>
    </div>

    <div class="api-design-body flex-column">
      <div class="api-param-example param-box">
        <IDE class="view" v-model="api.param" mode="application/json">
          <template #title><span :title="tips.paramTips">请求参数示例</span></template>
        </IDE>
        <IDE class="view" v-model="api.result" mode="application/json">
          <template #title><span :title="tips.resultTips">返回参数示例</span></template>
        </IDE>
      </div>
      <div class="api-param-explain param-box">
        <div class="view ide">
          <div class="ide-head flex-row-between flex-row-center">
            <span class="ide-title">请求参数说明</span>
            <div class="ide-action flex-row-center">
              <span title="格式化" @click="format" class="flex-row-center btn-format click">
                <Icon class="icon-format" type="format" />
              </span>
            </div>
          </div>
          <div class="ide-body">
            <div class="param-explain">
              <div class="grid-th">名称</div>
              <div class="grid-th">约束</div>
              <div class="grid-th">默认值</div>
              <div class="grid-th">备注</div>
              <div class="grid-th">添加</div>
              <input class="grid-td" />

              <div class="grid-td">
                <select class="grid-td">
                  <option value="int">int</option>
                  <option value="double">double</option>
                  <option value="object">object</option>
                  <option value="number">number</option>
                </select>
                <input class="grid-td" type="checkbox" />
                <input class="grid-td" />
              </div>

              <textarea class="grid-td" />

              <textarea class="grid-td" type="textarea" />

              <div class="grid-td">
                删除
              </div>
            </div>
          </div>
        </div>
        <div class="view"></div>
      </div>
    </div>
  </div>
</template>
<script>
import ApiDebug from "./ApiDebug";
import ApiGroup from "./ApiGroup";
import tips from "./tips.js";
let components = { ApiDebug, ApiGroup };
export default {
  components,
  props: ["apiData", "apiDoc", "type", "open", "apiIndex"],
  emits: ["remove"],
  data() {
    return {
      tips,
      visibleDesc: false,
      api1: this.apiData || {},
      ajax: null,
      res: null,
      showDebug: false,
      viewOpen: this.open
      // api: {}
    };
  },
  // updated() {
  //   console.warn("[Api][updated]");
  // },
  // inject: ["apiDoc"],
  computed: {
    api() {
      console.log(this.apiDoc, this.apiIndex);
      // return this.apiData.list[this.apiIndex] || {};
      return this.apiData;
    },
    viewTheme() {
      let themes = {
        get: "api-theme-get",
        post: "api-theme-post",
        put: "api-theme-put",
        head: "api-theme-head",
        delete: "api-theme-delete"
      };
      let css = {
        "api-design-open1": this.viewOpen
      };
      css[themes[this.api.method]] = true;
      return css;
    },
    resStr() {
      let res = this.res;
      if (!this.res) {
        return "";
      }
      let resStr = "";
      if (typeof res === "object") {
        resStr = JSON.stringify(res, null, 2);
      } else {
        resStr = res;
      }
      return resStr || "";
    },
    url() {
      let url = "--";
      try {
        url = new URL(this.api.url).href;
      } catch (error) {
        let baseURL = this.apiDoc.baseURL || "";
        let apiUrl = this.api.url || "";
        if (!baseURL.endsWith("/") && !apiUrl.startsWith("/")) {
          url = baseURL + "/" + apiUrl;
        } else if (baseURL.endsWith("/") && apiUrl.startsWith("/")) {
          url = baseURL + "/" + apiUrl.substr(1);
        } else {
          url = baseURL + apiUrl;
        }
      }
      return url;
    }
  },
  methods: {
    update(v) {
      console.log("[update]", v, this.api);
    },
    setApi() {
      let apiBase = {
        group: "默认分组",
        name: "新建接口",
        method: "get",
        url: "",
        param: this.tips.param,
        paramSet: this.tips.paramSet,
        result: this.tips.result,
        resultSet: this.tips.resultSet
      };
      this.api = Object.assign({}, apiBase, this.apiData);
    },
    format(key) {
      if (!this.api[key]) {
        return;
      }
      let val = this.api[key];
      if (typeof val == "object") {
        this.api[key] = JSON.stringify(val, null, 1);
      }
      if (typeof val == "string" && val.indexOf("{") >= 0) {
        try {
          try {
            let obj = JSON.parse(this.api[key]);
            this.api[key] = JSON.stringify(obj, null, 1);
          } catch (error) {
            window.eval("window.paramEval=" + this.api[key]);
            this.api[key] = JSON.stringify(window.paramEval, null, 1);
          }
        } catch (error) {
          window.alert(`仅支持Json,Object类型的参数格式化\n异常详情:\n` + error.message);
        }
      }
    },
    setRes(result) {
      this.res = result;
    },
    useRes() {
      let res = this.res;
      if (res && typeof res == "object") {
        res = JSON.stringify(res, null, 2);
      }
      res && this.$set(this.api, "result", res);
      this.showDebug = false;
      this.setRes(null);
      this.apiDebug(true);
    },
    apiDebug(cancel) {
      this.ajax && this.ajax.cancel("取消调试");
      this.setRes(null);
      if (cancel) {
        return (this.ajax = false);
      }
      let param = {
        ...this.api
      };
      try {
        // param.param = eval("(" + param.param + ")");
        // param.paramSet = eval("(" + param.paramSet + ")");
        // param.result = eval("(" + param.result + ")");
        // param.resultSet = eval("(" + param.resultSet + ")");
        param.param = new Function("return " + param.param)();
        param.paramSet = new Function("return " + param.paramSet)();
        param.result = new Function("return " + param.result)();
        param.resultSet = new Function(param.resultSet);
        console.log("[解析参数]", param);
      } catch (error) {
        console.error("[解析参数异常]", error, param);
        this.setRes(error.stack);
        return;
      }
      this.ajax = this.$_apiTool.axios.CancelToken.source();
      let config = {
        baseURL: this.apiDoc.baseURL,
        cancelToken: this.ajax.token
      };
      window.apiDebug(param, config).then((result) => {
        console.log("[apiDebug][result]", result);
        // setTimeout((ev) => (this.ajax = null), 100);
        this.ajax = null;
        this.setRes(result);
      });
    }
  }
};
</script>
<style src="./ApiDesign.css"></style>
<style>
.param-explain {
  display: grid;
  grid-template-columns: minmax(60px, auto)  auto auto minmax(50px, auto) 60px;
  font-size: 0.8rem;
  filter: grayscale(0.8);
}
.param-explain input {
  /* max-width: 100px; */
}
.grid-th {
  background-color: #f7f7f733;
  padding: 5px 10px;
  box-shadow: 0px 0px 1px 0px #ddd;
}

.grid-td {
  padding: 5px;
  box-shadow: 0px 0px 1px 1px #ddd;
}

.grid-td:nth-child(6n) {
  /* background-color: #fafafa; */
}

.form-item {
  display: flex;
  align-items: center;
  min-width: 260px;
  margin-right: 10px;
}
.form-item-label {
  min-width: 60px;
  flex-shrink: 0;
}
.form-item-content {
  flex-grow: 1;
  margin: 0 10px;
}
input.form-item-content {
  width: 300px;
}
.popover-plain .form-item {
  background: linear-gradient(145deg, #dcdfde 0%, #dae4e8 100%);
  border: 1px solid #cccc;
  border-radius: 5px;
  padding: 2px 5px;
  margin-inline-start: -5px;
  box-shadow: 2px 4px 25px #dddd, 0 0 15px 1px #dddd;
}
</style>
